package juc.blockqueue.linkedblockdeque;

/**
 * @ClassName DualEndProducerConsumer
 * @PackageName juc.blockqueue.linkedblockdeque
 * @projectName myThread
 * @Description 2. 生产者-消费者模式（双端操作）
 * @Author games
 * @Date 2025/9/4 下午3:16
 * @Version 1.0
 */
import java.util.concurrent.LinkedBlockingDeque;
import java.util.Random;

public class DualEndProducerConsumer {
    /**
     * 主方法：演示使用LinkedBlockingDeque实现优先级队列的生产者-消费者模型
     * 高优先级任务从队列头部插入，普通任务从队列尾部插入
     * 消费者总是从队列头部获取任务，确保高优先级任务优先处理
     * @param args 命令行参数（未使用）
     */
    public static void main(String[] args) {
        // 创建容量为10的链式阻塞双端队列
        LinkedBlockingDeque<String> deque = new LinkedBlockingDeque<>(10);
        Random random = new Random();

        // 高优先级生产者（从头部插入）
        Thread highPriorityProducer = new Thread(() -> {
            try {
                //for (int i = 1; i <= 5; i++) {
                for (;;) {
                    //String task = "High-Priority-Task-" + i;
                    String task = "High-Priority-Task-";
                    deque.putFirst(task); // 高优先级任务从头部插入
                    System.out.println("高优先级生产者添加: " + task);
                    Thread.sleep(500 + random.nextInt(1000));
                }
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        });

        // 普通生产者（从尾部插入）
        Thread normalProducer = new Thread(() -> {
            try {
                for (int i = 1; i <= 5; i++) {
                    String task = "Normal-Task-" + i;
                    deque.putLast(task); // 普通任务从尾部插入
                    System.out.println("普通生产者添加: " + task);
                    Thread.sleep(300 + random.nextInt(800));
                }
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        });

        // 消费者（从头部消费）
        Thread consumer = new Thread(() -> {
            try {
                //for (int i = 0; i < 10; i++) {
                for (; ;) {
                    String task = deque.takeFirst(); // 总是从头部获取（优先处理高优先级任务）
                    System.out.println("消费者处理: " + task);
                    Thread.sleep(400 + random.nextInt(600));
                }
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        });

        highPriorityProducer.start();
        normalProducer.start();
        consumer.start();
    }
}
